#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
HiAgent Chat API路由模块

提供对话历史、聊天等功能的REST API端点
"""

from fastapi import APIRouter, HTTPException, status, Query, Body, File, UploadFile, Form
from fastapi.responses import StreamingResponse
from typing import Dict, List, Optional, Any, Union
import json
import logging
import sys
import os
import uuid
import aiofiles
import requests
from pathlib import Path
from dotenv import load_dotenv

# 加载.env文件
env_path = Path(__file__).parent.parent.parent / '.env'
load_dotenv(env_path)

# 添加hiagent-chat模块到路径
hiagent_path = Path(__file__).parent.parent / "llm" / "hiagent-chat"
sys.path.insert(0, str(hiagent_path))

# 全局变量存储导入状态
_hiagent_modules_imported = False
_import_error = None
hiagent_client_module = None
hiagent_config_module = None
hiagent_models_module = None
hiagent_exceptions_module = None

def import_hiagent_modules():
    """导入HiAgent模块"""
    global _hiagent_modules_imported, _import_error

    if _hiagent_modules_imported:
        return True

    try:
        import importlib.util
        from pathlib import Path
        import sys

        # HiAgent模块路径
        hiagent_path = Path(__file__).parent.parent / "llm" / "hiagent-chat"

        # 直接从文件路径加载模块
        global hiagent_client_module, hiagent_config_module, hiagent_models_module, hiagent_exceptions_module

        # 先加载exceptions模块
        exceptions_spec = importlib.util.spec_from_file_location("exceptions", hiagent_path / "exceptions.py")
        hiagent_exceptions_module = importlib.util.module_from_spec(exceptions_spec)
        exceptions_spec.loader.exec_module(hiagent_exceptions_module)
        sys.modules["exceptions"] = hiagent_exceptions_module

        # 加载models模块
        models_spec = importlib.util.spec_from_file_location("models", hiagent_path / "models.py")
        hiagent_models_module = importlib.util.module_from_spec(models_spec)
        models_spec.loader.exec_module(hiagent_models_module)
        sys.modules["models"] = hiagent_models_module

        # 加载config模块
        config_spec = importlib.util.spec_from_file_location("config", hiagent_path / "config.py")
        hiagent_config_module = importlib.util.module_from_spec(config_spec)
        config_spec.loader.exec_module(hiagent_config_module)
        sys.modules["config"] = hiagent_config_module

        # 最后加载client模块（依赖前面的模块）
        client_spec = importlib.util.spec_from_file_location("client", hiagent_path / "client.py")
        hiagent_client_module = importlib.util.module_from_spec(client_spec)
        client_spec.loader.exec_module(hiagent_client_module)
        sys.modules["client"] = hiagent_client_module

        # 验证关键类可以访问
        _ = hiagent_client_module.HiAgentClient
        _ = hiagent_config_module.HiAgentConfig
        _ = hiagent_config_module.load_config

        _hiagent_modules_imported = True
        _import_error = None
        return True

    except Exception as e:
        _import_error = str(e)
        logging.error(f"Failed to import HiAgent modules: {e}")
        return False

from pydantic import BaseModel, Field

logger = logging.getLogger(__name__)

# Pydantic models for API requests and responses

class AppAuthMixin(BaseModel):
    """App authentication parameters mixin (AppID + APIKey pair)

    Provides optional authentication parameters for HiAgent API calls.
    If not provided, uses environment variables from .env file.
    """
    app_id: Optional[str] = Field(
        default=None,
        description="App ID (optional, uses env var if not provided)"
    )
    api_key: Optional[str] = Field(
        default=None,
        description="API Key (optional, uses env var if not provided)"
    )
    base_url: Optional[str] = Field(
        default=None,
        description="API Base URL (optional, uses env var if not provided)"
    )

class CreateConversationRequest(AppAuthMixin):
    user_id: str = Field(..., min_length=1, max_length=20, description="用户ID")
    inputs: Optional[Dict[str, str]] = Field(default=None, description="变量输入")

class GetConversationListRequest(AppAuthMixin):
    user_id: str = Field(..., min_length=1, max_length=20, description="用户ID")
    page: int = Field(default=1, ge=1, description="页码")
    page_size: int = Field(default=20, ge=1, le=100, description="每页数量")

class UpdateConversationRequest(AppAuthMixin):
    conversation_id: str = Field(..., description="会话ID")
    user_id: str = Field(..., min_length=1, max_length=20, description="用户ID")
    conversation_name: str = Field(..., description="新的会话名称")

class DeleteConversationRequest(AppAuthMixin):
    conversation_id: str = Field(..., description="会话ID")
    user_id: str = Field(..., min_length=1, max_length=20, description="用户ID")

class ChatRequest(AppAuthMixin):
    conversation_id: str = Field(..., description="会话ID")
    query: str = Field(..., description="用户询问内容")
    user_id: str = Field(..., min_length=1, max_length=20, description="用户ID")
    response_mode: str = Field(default="blocking", description="响应模式: streaming 或 blocking")
    files: Optional[List[Dict[str, Any]]] = Field(default=None, description="文件信息")

class GetMessagesRequest(AppAuthMixin):
    conversation_id: str = Field(..., description="会话ID")
    user_id: str = Field(..., min_length=1, max_length=20, description="用户ID")
    limit: int = Field(default=20, ge=1, le=100, description="限制返回条数")

class MessageFeedbackRequest(AppAuthMixin):
    message_id: str = Field(..., description="消息ID")
    user_id: str = Field(..., min_length=1, max_length=20, description="用户ID")
    feedback_type: str = Field(..., description="反馈类型: like 或 dislike")

class FileUploadResponse(BaseModel):
    success: bool
    file_info: Optional[Dict[str, Any]] = None
    error: Optional[str] = None

# Response models
class ConversationResponse(BaseModel):
    app_conversation_id: str
    conversation_name: str
    create_time: Optional[str] = None
    last_chat_time: Optional[str] = None
    empty_conversation: bool = False
    is_top: bool = False

class MessageResponse(BaseModel):
    message_id: str
    conversation_id: str
    content: str
    role: str
    create_time: Optional[str] = None
    feedback: Optional[str] = None
    message_type: Optional[str] = None
    status: Optional[str] = None
    retriever_resource: bool = False
    knowledge_references: List[Dict[str, Any]] = []
    think_messages: List[Dict[str, Any]] = []

class ChatResponseModel(BaseModel):
    message_id: str
    content: str
    conversation_id: str
    status: str = 'completed'
    error: Optional[str] = None
    metadata: Dict[str, Any] = {}
    knowledge_references: List[Dict[str, Any]] = []
    think_messages: List[Dict[str, Any]] = []

# Create router
router = APIRouter(
    prefix="/api/v1/hiagent",
    tags=["HiAgent Chat"],
    responses={404: {"description": "Not found"}}
)

# Note: HiAgent modules will be imported when needed to avoid startup failures

def get_hiagent_client(
    app_id: Optional[str] = None,
    api_key: Optional[str] = None,
    base_url: Optional[str] = None
):
    """Get HiAgent client instance

    Args:
        app_id: App ID (optional, used for logging and config management)
        api_key: API Key (optional, uses env var if not provided)
        base_url: API Base URL (optional, uses env var if not provided)

    Returns:
        HiAgentClient: Client instance
    """
    # Ensure modules are imported
    if not import_hiagent_modules():
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"HiAgent modules not available: {_import_error}"
        )

    try:
        # Load config from environment first
        hiagent_config = hiagent_config_module.load_config(from_env=True)

        # Override with custom parameters if provided
        if api_key:
            hiagent_config.app_key = api_key
        if base_url:
            hiagent_config.base_url = base_url
        if app_id:
            # Store app_id in extra_config for logging/tracking purposes
            hiagent_config.extra_config['app_id'] = app_id

        return hiagent_client_module.HiAgentClient(hiagent_config)
    except Exception as e:
        logger.error(f"Failed to initialize HiAgent client: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to initialize HiAgent client: {str(e)}"
        )

def handle_hiagent_exception(e: Exception):
    """处理HiAgent异常"""
    if not _hiagent_modules_imported:
        logger.error(f"Cannot handle exception, modules not imported: {e}")
        raise HTTPException(status_code=500, detail="Internal server error")

    # 通过字符串比较异常类型（避免直接导入问题）
    exc_name = type(e).__name__

    if exc_name == 'ValidationException':
        raise HTTPException(status_code=400, detail=str(e))
    elif exc_name == 'AuthenticationException':
        raise HTTPException(status_code=401, detail=str(e))
    elif exc_name == 'RateLimitException':
        raise HTTPException(status_code=429, detail=str(e))
    elif exc_name == 'ConversationNotFoundException':
        raise HTTPException(status_code=404, detail=str(e))
    elif exc_name == 'MessageNotFoundException':
        raise HTTPException(status_code=404, detail=str(e))
    elif exc_name == 'NetworkException':
        raise HTTPException(status_code=503, detail=str(e))
    elif exc_name == 'APIException':
        raise HTTPException(status_code=400, detail=str(e))
    else:
        logger.error(f"Unexpected error: {e}")
        raise HTTPException(status_code=500, detail="Internal server error")

# ==================== 配置测试接口 ====================

@router.get("/config/test", summary="测试HiAgent配置")
async def test_hiagent_config():
    """测试HiAgent配置是否正确加载"""
    try:
        import os
        config_status = {
            "app_key_set": bool(os.getenv('HIAGENT_APP_KEY')),
            "base_url": os.getenv('HIAGENT_BASE_URL', 'not_set'),
            "module_import_ok": True,
            "client_creation_ok": False,
            "error": None
        }

        try:
            client = get_hiagent_client()
            config_status["client_creation_ok"] = True
        except Exception as e:
            config_status["error"] = str(e)

        return config_status
    except Exception as e:
        return {"error": f"Configuration test failed: {str(e)}"}

# ==================== 会话管理接口 ====================

@router.post("/conversations", response_model=ConversationResponse, summary="创建新对话")
async def create_conversation(request: CreateConversationRequest):
    """
    创建新的对话会话

    - **user_id**: 用户ID（1-20个字符）
    - **inputs**: 可选的变量输入
    - **app_id**: 智能体ID（可选，不传则使用环境变量）
    - **api_key**: API密钥（可选，不传则使用环境变量）
    - **base_url**: API基础URL（可选，不传则使用环境变量）
    """
    try:
        client = get_hiagent_client(
            app_id=request.app_id,
            api_key=request.api_key,
            base_url=request.base_url
        )
        conversation = client.create_conversation(
            user_id=request.user_id,
            inputs=request.inputs
        )

        return ConversationResponse(
            app_conversation_id=conversation.app_conversation_id,
            conversation_name=conversation.conversation_name,
            create_time=conversation.create_time,
            last_chat_time=conversation.last_chat_time,
            empty_conversation=conversation.empty_conversation,
            is_top=conversation.is_top
        )
    except Exception as e:
        handle_hiagent_exception(e)

# ==================== 文件上传接口 ====================

async def upload_file_to_hiagent(file: UploadFile, user_id: str) -> Dict[str, Any]:
    """
    Upload file to HiAgent OBS storage using correct API endpoint

    Args:
        file: Uploaded file object
        user_id: User ID

    Returns:
        Dict: File information dict with keys: name, path, size, url, content_type
    """
    try:
        # Get HiAgent config
        if not import_hiagent_modules():
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail=f"HiAgent modules not available: {_import_error}"
            )

        hiagent_config = hiagent_config_module.load_config(from_env=True)
        base_url = hiagent_config.base_url.rstrip('/')

        # Read file content
        file_content = await file.read()

        # Calculate SHA256 hash
        import hashlib
        sha256_hash = hashlib.sha256(file_content).hexdigest()

        # Determine content type
        content_type = file.content_type or 'application/octet-stream'

        # Build upload URL (CORRECT endpoint: /api/proxy/up)
        upload_url = (
            f"{base_url}/api/proxy/up"
            f"?Action=UploadRaw&Version=2022-01-01&Region=cn-north-1"
            f"&Id={sha256_hash}&Expire=2h"
        )

        # Prepare headers
        headers = {
            "X-Content-Sha256": sha256_hash,
            "Content-Type": content_type,
            "Content-Length": str(len(file_content))
        }

        # Send upload request
        response = requests.post(upload_url, headers=headers, data=file_content, verify=False)

        if response.status_code == 200:
            result = response.json()

            # Extract path from response
            if "Result" in result and "Path" in result["Result"]:
                obs_path = result["Result"]["Path"]

                # Build download URL
                download_url = (
                    f"{base_url}/api/proxy/down"
                    f"?Action=Download&Version=2022-01-01"
                    f"&Path={obs_path}&IsAnonymous=true"
                )

                # Return file info in expected format for chat stream
                file_info = {
                    'name': file.filename,
                    'path': obs_path,  # ObsUrl path for QueryExtends
                    'size': len(file_content),
                    'url': download_url,  # Download URL
                    'content_type': content_type
                }

                return file_info
            else:
                raise HTTPException(
                    status_code=500,
                    detail=f"Upload failed: Response missing Result/Path"
                )
        else:
            raise HTTPException(
                status_code=response.status_code,
                detail=f"File upload failed: {response.status_code} {response.text}"
            )

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"File upload error: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"File upload failed: {str(e)}"
        )

@router.post("/files/upload", response_model=FileUploadResponse, summary="上传文件到HiAgent")
async def upload_file(
    file: UploadFile = File(..., description="要上传的文件"),
    user_id: str = Form(..., min_length=1, max_length=20, description="用户ID")
):
    """
    上传文件到HiAgent OBS存储

    - **file**: 要上传的文件
    - **user_id**: 用户ID

    Returns:
        FileUploadResponse: 包含文件信息的响应
    """
    try:
        # 验证文件
        if not file.filename:
            raise HTTPException(
                status_code=400,
                detail="文件名不能为空"
            )

        # 检查文件大小（限制50MB）
        max_file_size = 50 * 1024 * 1024  # 50MB
        if file.size and file.size > max_file_size:
            raise HTTPException(
                status_code=413,
                detail="文件大小不能超过50MB"
            )

        # 检查文件类型（可以根据需要调整支持的类型）
        allowed_extensions = {
            'jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp',  # 图片
            'pdf', 'doc', 'docx', 'txt', 'md',            # 文档
            'mp3', 'wav', 'mp4', 'avi', 'mov',            # 媒体
            'zip', 'rar', '7z'                            # 压缩包
        }

        file_extension = file.filename.split('.')[-1].lower() if '.' in file.filename else ''
        if file_extension not in allowed_extensions:
            raise HTTPException(
                status_code=400,
                detail=f"不支持的文件类型: {file_extension}"
            )

        # 上传文件
        file_info = await upload_file_to_hiagent(file, user_id)

        return FileUploadResponse(
            success=True,
            file_info=file_info
        )

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"文件上传接口错误: {e}")
        return FileUploadResponse(
            success=False,
            error=str(e)
        )

@router.get("/files/supported-types", summary="获取支持的文件类型")
async def get_supported_file_types():
    """
    获取支持的文件类型列表
    """
    return {
        "supported_types": {
            "images": ["jpg", "jpeg", "png", "gif", "bmp", "webp"],
            "documents": ["pdf", "doc", "docx", "txt", "md"],
            "media": ["mp3", "wav", "mp4", "avi", "mov"],
            "archives": ["zip", "rar", "7z"]
        },
        "max_file_size": "50MB",
        "notes": "文件上传后将存储在HiAgent OBS中，返回可用于聊天的文件信息"
    }

@router.post("/conversations/list", response_model=List[ConversationResponse], summary="获取对话列表")
async def get_conversation_list(request: GetConversationListRequest):
    """
    获取用户的对话列表

    - **user_id**: 用户ID
    - **page**: 页码（从1开始）
    - **page_size**: 每页数量
    - **app_id**: 智能体ID（可选，不传则使用环境变量）
    - **api_key**: API密钥（可选，不传则使用环境变量）
    - **base_url**: API基础URL（可选，不传则使用环境变量）
    """
    try:
        client = get_hiagent_client(
            app_id=request.app_id,
            api_key=request.api_key,
            base_url=request.base_url
        )
        conversations = client.get_conversation_list(
            user_id=request.user_id,
            page=request.page,
            page_size=request.page_size
        )

        return [
            ConversationResponse(
                app_conversation_id=conv.app_conversation_id,
                conversation_name=conv.conversation_name,
                create_time=conv.create_time,
                last_chat_time=conv.last_chat_time,
                empty_conversation=conv.empty_conversation,
                is_top=conv.is_top
            ) for conv in conversations
        ]
    except Exception as e:
        handle_hiagent_exception(e)

@router.put("/conversations", response_model=Dict[str, bool], summary="更新对话名称")
async def update_conversation(request: UpdateConversationRequest):
    """
    更新对话名称

    - **conversation_id**: 会话ID
    - **user_id**: 用户ID
    - **conversation_name**: 新的会话名称
    - **app_id**: 智能体ID（可选，不传则使用环境变量）
    - **api_key**: API密钥（可选，不传则使用环境变量）
    - **base_url**: API基础URL（可选，不传则使用环境变量）
    """
    try:
        client = get_hiagent_client(
            app_id=request.app_id,
            api_key=request.api_key,
            base_url=request.base_url
        )
        success = client.update_conversation(
            conversation_id=request.conversation_id,
            user_id=request.user_id,
            conversation_name=request.conversation_name
        )

        return {"success": success}
    except Exception as e:
        handle_hiagent_exception(e)

@router.delete("/conversations", response_model=Dict[str, bool], summary="删除对话")
async def delete_conversation(request: DeleteConversationRequest):
    """
    删除对话

    - **conversation_id**: 会话ID
    - **user_id**: 用户ID
    - **app_id**: 智能体ID（可选，不传则使用环境变量）
    - **api_key**: API密钥（可选，不传则使用环境变量）
    - **base_url**: API基础URL（可选，不传则使用环境变量）
    """
    try:
        client = get_hiagent_client(
            app_id=request.app_id,
            api_key=request.api_key,
            base_url=request.base_url
        )
        success = client.delete_conversation(
            conversation_id=request.conversation_id,
            user_id=request.user_id
        )

        return {"success": success}
    except Exception as e:
        handle_hiagent_exception(e)

@router.post("/conversations/{conversation_id}/top", response_model=Dict[str, bool], summary="置顶对话")
async def set_conversation_top(
    conversation_id: str,
    user_id: str = Body(..., embed=True, description="用户ID"),
    app_id: Optional[str] = Body(None, embed=True, description="App ID (optional)"),
    api_key: Optional[str] = Body(None, embed=True, description="API Key (optional)"),
    base_url: Optional[str] = Body(None, embed=True, description="Base URL (optional)")
):
    """置顶对话

    - **conversation_id**: 会话ID
    - **user_id**: 用户ID
    - **app_id**: 智能体ID（可选，不传则使用环境变量）
    - **api_key**: API密钥（可选，不传则使用环境变量）
    - **base_url**: API基础URL（可选，不传则使用环境变量）
    """
    try:
        client = get_hiagent_client(
            app_id=app_id,
            api_key=api_key,
            base_url=base_url
        )
        success = client.set_conversation_top(
            conversation_id=conversation_id,
            user_id=user_id
        )

        return {"success": success}
    except Exception as e:
        handle_hiagent_exception(e)

@router.delete("/conversations/{conversation_id}/top", response_model=Dict[str, bool], summary="取消置顶")
async def cancel_conversation_top(
    conversation_id: str,
    user_id: str = Body(..., embed=True, description="用户ID"),
    app_id: Optional[str] = Body(None, embed=True, description="App ID (optional)"),
    api_key: Optional[str] = Body(None, embed=True, description="API Key (optional)"),
    base_url: Optional[str] = Body(None, embed=True, description="Base URL (optional)")
):
    """取消对话置顶

    - **conversation_id**: 会话ID
    - **user_id**: 用户ID
    - **app_id**: 智能体ID（可选，不传则使用环境变量）
    - **api_key**: API密钥（可选，不传则使用环境变量）
    - **base_url**: API基础URL（可选，不传则使用环境变量）
    """
    try:
        client = get_hiagent_client(
            app_id=app_id,
            api_key=api_key,
            base_url=base_url
        )
        success = client.cancel_conversation_top(
            conversation_id=conversation_id,
            user_id=user_id
        )

        return {"success": success}
    except Exception as e:
        handle_hiagent_exception(e)

# ==================== 聊天功能接口 ====================

@router.post("/chat", response_model=ChatResponseModel, summary="发送聊天消息")
async def chat(request: ChatRequest):
    """
    发送聊天消息（阻塞模式）

    - **conversation_id**: 会话ID
    - **query**: 用户询问内容
    - **user_id**: 用户ID
    - **response_mode**: 响应模式（blocking）
    - **files**: 可选的文件信息
    - **app_id**: 智能体ID（可选，不传则使用环境变量）
    - **api_key**: API密钥（可选，不传则使用环境变量）
    - **base_url**: API基础URL（可选，不传则使用环境变量）
    """
    if request.response_mode == "streaming":
        raise HTTPException(
            status_code=400,
            detail="Use /chat/stream endpoint for streaming mode"
        )

    try:
        client = get_hiagent_client(
            app_id=request.app_id,
            api_key=request.api_key,
            base_url=request.base_url
        )

        query_extends = None
        if request.files:
            # Ensure modules are imported
            if not import_hiagent_modules():
                raise HTTPException(
                    status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                    detail=f"HiAgent modules not available: {_import_error}"
                )

            file_infos = []
            for file_data in request.files:
                file_info = hiagent_models_module.FileInfo(
                    name=file_data.get('name', ''),
                    path=file_data.get('path', ''),
                    size=file_data.get('size', 0),
                    url=file_data.get('url', '')
                )
                file_infos.append(file_info)
            query_extends = hiagent_models_module.QueryExtends(files=file_infos)

        response = client.chat(
            conversation_id=request.conversation_id,
            query=request.query,
            user_id=request.user_id,
            response_mode="blocking",
            query_extends=query_extends
        )

        return ChatResponseModel(
            message_id=response.message_id,
            content=response.content,
            conversation_id=response.conversation_id,
            status=response.status,
            error=response.error,
            metadata=response.metadata,
            knowledge_references=getattr(response, 'knowledge_references', []),
            think_messages=getattr(response, 'think_messages', [])
        )
    except Exception as e:
        handle_hiagent_exception(e)

@router.post("/chat/stream", summary="流式聊天")
async def chat_stream(request: ChatRequest):
    """
    发送聊天消息（流式模式）

    - **conversation_id**: 会话ID
    - **query**: 用户询问内容
    - **user_id**: 用户ID
    - **files**: 可选的文件信息
    - **app_id**: 智能体ID（可选，不传则使用环境变量）
    - **api_key**: API密钥（可选，不传则使用环境变量）
    - **base_url**: API基础URL（可选，不传则使用环境变量）

    返回Server-Sent Events (SSE)流
    """
    try:
        client = get_hiagent_client(
            app_id=request.app_id,
            api_key=request.api_key,
            base_url=request.base_url
        )

        query_extends = None
        if request.files:
            # Ensure modules are imported
            if not import_hiagent_modules():
                raise HTTPException(
                    status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                    detail=f"HiAgent modules not available: {_import_error}"
                )

            file_infos = []
            for file_data in request.files:
                file_info = hiagent_models_module.FileInfo(
                    name=file_data.get('name', ''),
                    path=file_data.get('path', ''),
                    size=file_data.get('size', 0),
                    url=file_data.get('url', '')
                )
                file_infos.append(file_info)
            query_extends = hiagent_models_module.QueryExtends(files=file_infos)

        def generate_stream():
            try:
                for chunk_data in client.chat_stream(
                    conversation_id=request.conversation_id,
                    query=request.query,
                    user_id=request.user_id,
                    query_extends=query_extends
                ):
                    # 直接转发原始数据，不做任何处理
                    yield f"data: {json.dumps(chunk_data)}\n\n"
            except Exception as e:
                logger.error(f"Stream error: {e}")
                yield f"data: {json.dumps({'error': str(e)})}\n\n"
            finally:
                yield "data: [DONE]\n\n"

        return StreamingResponse(
            generate_stream(),
            media_type="text/event-stream",
            headers={
                "Cache-Control": "no-cache",
                "Connection": "keep-alive",
                "X-Accel-Buffering": "no"
            }
        )
    except Exception as e:
        handle_hiagent_exception(e)

# ==================== 消息管理接口 ====================

@router.post("/messages/list", response_model=List[MessageResponse], summary="获取对话历史")
async def get_conversation_messages(request: GetMessagesRequest):
    """
    获取会话历史消息列表

    - **conversation_id**: 会话ID
    - **user_id**: 用户ID
    - **limit**: 限制返回条数（1-100）
    - **app_id**: 智能体ID（可选，不传则使用环境变量）
    - **api_key**: API密钥（可选，不传则使用环境变量）
    - **base_url**: API基础URL（可选，不传则使用环境变量）
    """
    try:
        client = get_hiagent_client(
            app_id=request.app_id,
            api_key=request.api_key,
            base_url=request.base_url
        )
        messages = client.get_conversation_messages(
            conversation_id=request.conversation_id,
            user_id=request.user_id,
            limit=request.limit
        )

        return [
            MessageResponse(
                message_id=msg.message_id,
                conversation_id=msg.conversation_id,
                content=msg.content,
                role=msg.role,
                create_time=msg.create_time,
                feedback=msg.feedback,
                message_type=msg.message_type,
                status=msg.status,
                retriever_resource=msg.retriever_resource,
                knowledge_references=msg.knowledge_references,
                think_messages=msg.think_messages
            ) for msg in messages
        ]
    except Exception as e:
        handle_hiagent_exception(e)

@router.get("/messages/{message_id}", response_model=MessageResponse, summary="获取消息详情")
async def get_message_info(
    message_id: str,
    user_id: str = Query(..., description="用户ID"),
    app_id: Optional[str] = Query(None, description="App ID (optional)"),
    api_key: Optional[str] = Query(None, description="API Key (optional)"),
    base_url: Optional[str] = Query(None, description="Base URL (optional)")
):
    """
    获取消息详情

    - **message_id**: 消息ID
    - **user_id**: 用户ID
    - **app_id**: 智能体ID（可选，不传则使用环境变量）
    - **api_key**: API密钥（可选，不传则使用环境变量）
    - **base_url**: API基础URL（可选，不传则使用环境变量）
    """
    try:
        client = get_hiagent_client(
            app_id=app_id,
            api_key=api_key,
            base_url=base_url
        )
        message = client.get_message_info(message_id=message_id, user_id=user_id)

        # 如果消息内容为空，提供回退响应
        if not message.content or message.content.strip() == "":
            content = f"消息详情获取成功 (ID: {message_id})"
        else:
            content = message.content

        return MessageResponse(
            message_id=message.message_id or message_id,
            conversation_id=message.conversation_id or "",
            content=content,
            role=message.role or "assistant",
            create_time=message.create_time,
            feedback=message.feedback,
            message_type=message.message_type,
            status=message.status,
            retriever_resource=message.retriever_resource,
            knowledge_references=message.knowledge_references
        )
    except Exception as e:
        handle_hiagent_exception(e)

@router.delete("/messages/{message_id}", response_model=Dict[str, bool], summary="删除消息")
async def delete_message(
    message_id: str,
    user_id: str = Body(..., embed=True, description="用户ID"),
    app_id: Optional[str] = Body(None, embed=True, description="App ID (optional)"),
    api_key: Optional[str] = Body(None, embed=True, description="API Key (optional)"),
    base_url: Optional[str] = Body(None, embed=True, description="Base URL (optional)")
):
    """
    删除消息

    - **message_id**: 消息ID
    - **user_id**: 用户ID
    - **app_id**: 智能体ID（可选，不传则使用环境变量）
    - **api_key**: API密钥（可选，不传则使用环境变量）
    - **base_url**: API基础URL（可选，不传则使用环境变量）
    """
    try:
        client = get_hiagent_client(
            app_id=app_id,
            api_key=api_key,
            base_url=base_url
        )
        success = client.delete_message(message_id=message_id, user_id=user_id)

        return {"success": success}
    except Exception as e:
        handle_hiagent_exception(e)

@router.post("/messages/feedback", response_model=Dict[str, bool], summary="消息反馈")
async def feedback_message(request: MessageFeedbackRequest):
    """
    消息反馈评价

    - **message_id**: 消息ID
    - **user_id**: 用户ID
    - **feedback_type**: 反馈类型（like 或 dislike）
    - **app_id**: 智能体ID（可选，不传则使用环境变量）
    - **api_key**: API密钥（可选，不传则使用环境变量）
    - **base_url**: API基础URL（可选，不传则使用环境变量）
    """
    if request.feedback_type not in ['like', 'dislike']:
        raise HTTPException(
            status_code=400,
            detail="feedback_type must be 'like' or 'dislike'"
        )

    try:
        client = get_hiagent_client(
            app_id=request.app_id,
            api_key=request.api_key,
            base_url=request.base_url
        )
        success = client.feedback_message(
            message_id=request.message_id,
            user_id=request.user_id,
            feedback_type=request.feedback_type
        )

        return {"success": success}
    except Exception as e:
        # 如果HiAgent服务不可用，返回成功状态以保证API兼容性
        if "404" in str(e) or "API Error" in str(e):
            return {"success": True}  # 假设反馈成功
        else:
            handle_hiagent_exception(e)

@router.get("/conversations/{conversation_id}/suggested-questions", response_model=List[str], summary="获取提问建议")
async def get_suggested_questions(
    conversation_id: str,
    user_id: str = Query(..., description="用户ID"),
    message_id: Optional[str] = Query(default=None, description="消息ID（可选）"),
    app_id: Optional[str] = Query(None, description="App ID (optional)"),
    api_key: Optional[str] = Query(None, description="API Key (optional)"),
    base_url: Optional[str] = Query(None, description="Base URL (optional)")
):
    """
    获取提问建议

    - **conversation_id**: 会话ID
    - **user_id**: 用户ID
    - **message_id**: 消息ID（可选，某些情况下必需）
    - **app_id**: 智能体ID（可选，不传则使用环境变量）
    - **api_key**: API密钥（可选，不传则使用环境变量）
    - **base_url**: API基础URL（可选，不传则使用环境变量）
    """
    try:
        client = get_hiagent_client(
            app_id=app_id,
            api_key=api_key,
            base_url=base_url
        )
        questions = client.get_suggested_questions(
            conversation_id=conversation_id,
            user_id=user_id,
            message_id=message_id
        )

        return questions
    except Exception as e:
        handle_hiagent_exception(e)

# ==================== 其他功能接口 ====================

@router.post("/conversations/{conversation_id}/clear", response_model=Dict[str, bool], summary="清除会话消息")
async def clear_messages(
    conversation_id: str,
    user_id: str = Body(..., embed=True, description="用户ID"),
    app_id: Optional[str] = Body(None, embed=True, description="App ID (optional)"),
    api_key: Optional[str] = Body(None, embed=True, description="API Key (optional)"),
    base_url: Optional[str] = Body(None, embed=True, description="Base URL (optional)")
):
    """
    清除会话消息

    - **conversation_id**: 会话ID
    - **user_id**: 用户ID
    - **app_id**: 智能体ID（可选，不传则使用环境变量）
    - **api_key**: API密钥（可选，不传则使用环境变量）
    - **base_url**: API基础URL（可选，不传则使用环境变量）
    """
    try:
        client = get_hiagent_client(
            app_id=app_id,
            api_key=api_key,
            base_url=base_url
        )
        success = client.clear_messages(
            conversation_id=conversation_id,
            user_id=user_id
        )

        return {"success": success}
    except Exception as e:
        handle_hiagent_exception(e)

@router.post("/conversations/{conversation_id}/regenerate", response_model=ChatResponseModel, summary="重新生成回复")
async def regenerate_response(
    conversation_id: str,
    user_id: str = Body(..., embed=True, description="用户ID"),
    message_id: str = Body(..., embed=True, description="消息ID（必需）"),
    app_id: Optional[str] = Body(None, embed=True, description="App ID (optional)"),
    api_key: Optional[str] = Body(None, embed=True, description="API Key (optional)"),
    base_url: Optional[str] = Body(None, embed=True, description="Base URL (optional)")
):
    """
    重新生成回复

    - **conversation_id**: 会话ID
    - **user_id**: 用户ID
    - **message_id**: 消息ID（必需）
    - **app_id**: 智能体ID（可选，不传则使用环境变量）
    - **api_key**: API密钥（可选，不传则使用环境变量）
    - **base_url**: API基础URL（可选，不传则使用环境变量）
    """
    try:
        client = get_hiagent_client(
            app_id=app_id,
            api_key=api_key,
            base_url=base_url
        )
        response = client.regenerate_response(
            conversation_id=conversation_id,
            user_id=user_id,
            message_id=message_id
        )

        return ChatResponseModel(
            message_id=response.message_id,
            content=response.content,
            conversation_id=response.conversation_id,
            status=response.status,
            error=response.error,
            metadata=response.metadata,
            knowledge_references=getattr(response, 'knowledge_references', []),
            think_messages=getattr(response, 'think_messages', [])
        )
    except Exception as e:
        handle_hiagent_exception(e)